package parse;



import hypergraph.HyperEdge;
import hypergraph.HyperGraph;
import hypergraph.Node;

import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Scanner;


public class Parse {
	
		public static HyperGraph readHyperGraph( String fileName )  throws Exception {
		
		HyperGraph hGraph = new HyperGraph();
		HashMap<String, Node> nodesMap=new HashMap<String, Node>();

		Scanner scanner = new Scanner(new FileReader( fileName ));
		
		String firstLine=null;
		String source=null;
		String destiny=null;
		
		try{
			while( scanner.hasNextLine() ){
				
				firstLine=scanner.nextLine();
				if( !firstLine.startsWith( "#" )){ // Si no es un comentario
					break;
				}
			}
			source  = firstLine;
			destiny = scanner.nextLine();
			
			while( scanner.hasNextLine()){
				
				String token=scanner.nextLine();
				if( !token.startsWith( "#" ) ){ // Si no es un comentario
					
					Scanner line = new Scanner( token );
					String name = line.next();
					if( name.length() > 10 ){
						throw new IllegalArgumentException( " Name to long" );
					}
					int weight = line.nextInt();
					int heads = line.nextInt();
					
					List<Node> headList = new ArrayList<Node>();
					List<Node> tailList = new ArrayList<Node>();
					
					while( heads-- != 0){
						String nodeName = line.next();
						appendNode( nodesMap, nodeName, headList );
					}
					
					int tails = line.nextInt();
					
					while( tails-- != 0){
						String nodeName = line.next();
						appendNode( nodesMap, nodeName, tailList);
					}
					
					HyperEdge hEdge= new HyperEdge( name, weight, tailList, headList );
					
					if( !hGraph.add( hEdge ) ){
						throw new IllegalArgumentException( "hyperedge already exists" );					
					}
					
					for( Node node: tailList ){
						node.add( hEdge );
					}
				}
				
			}
		} catch (Exception e) {
			throw new NoSuchElementException( "Empty Line" );
		}
		
		
		Node nodeDestiny=nodesMap.get( destiny );
		Node nodeSource =nodesMap.get( source );
		
		if( nodeDestiny==null || nodeSource==null ){
			throw new IllegalArgumentException( "Missing node destiny or source" );
		}
		
		hGraph.setDestiny( nodesMap.get( destiny ) );
		hGraph.setOrigin( nodesMap.get( source ) );
		return hGraph;
	}
	
	private static Node appendNode( HashMap<String,Node> nodesMap, String nodeName, List<Node> headList ){

		Node node;
		
		if( !nodesMap.containsKey( nodeName )){
			node=new Node(nodeName);
			nodesMap.put(nodeName, node);
		} else {
			node=nodesMap.get( nodeName );
		}
		headList.add( node );
		
		return node;
	}
	
}